﻿using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;

namespace AspNetCore.Web.Security.Provider
{
    /// <summary>
    /// token供应者
    /// </summary>
    public class TokenProvider : ITokenProvider
    {
        private IHttpContextAccessor _httpContextAccessor;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="httpContextAccessor"></param>
        public TokenProvider(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        /// <summary>
        ///  获取token的值
        /// </summary>
        /// <param name="scheme"></param>
        /// <param name="claimsIssuer"></param>
        /// <param name="headerKey"></param>
        /// <returns></returns>
        public string GetToken(string scheme, string claimsIssuer, string headerKey)
        {
            string token = string.Empty;

            var result = _httpContextAccessor.HttpContext.AuthenticateAsync(scheme).Result;
            if (result.Succeeded)
            {
                var claim = result.Principal.FindFirst(o => o.Type == ClaimTypes.Sid && o.Issuer.Equals(claimsIssuer));
                if (claim != null)
                    token = claim.Value;
            }
            else
            {
                if (_httpContextAccessor.HttpContext.Request.Headers != null)
                {
                    var adminTokenHeaders = _httpContextAccessor.HttpContext.Request.Headers[headerKey];
                    if (!StringValues.IsNullOrEmpty(adminTokenHeaders))
                        token = adminTokenHeaders.FirstOrDefault();
                }
            }
            return token;
        }

        /// <summary>
        /// cookie 获取token值
        /// </summary>
        /// <param name="scheme"></param>
        /// <param name="claimsIssuer"></param>
        /// <returns></returns>
        public string GetToken(string scheme, string claimsIssuer)
        {
            string token = string.Empty;

            var result = _httpContextAccessor.HttpContext.AuthenticateAsync(scheme).Result;
            if (result.Succeeded)
            {
                var claim = result.Principal.FindFirst(o => o.Type == ClaimTypes.Sid && o.Issuer.Equals(claimsIssuer));
                if (claim != null)
                    token = claim.Value;
            }
            return token;
        }

        /// <summary>
        /// 从 header获取token
        /// </summary>
        /// <param name="headerKey"></param>
        /// <returns></returns>
        public string GetToken(string headerKey)
        {
            string token = string.Empty;
            if (_httpContextAccessor.HttpContext.Request.Headers != null)
            {
                var adminTokenHeaders = _httpContextAccessor.HttpContext.Request.Headers[headerKey];
                if (!StringValues.IsNullOrEmpty(adminTokenHeaders))
                    token = adminTokenHeaders.FirstOrDefault();
            }
            return token;
        }

        /// <summary>
        /// 存储token
        /// </summary>
        /// <param name="scheme"></param>
        /// <param name="token"></param>
        /// <param name="name"></param>
        /// <param name="claimsIssuer"></param>
        public void Store(string scheme, string token, string name,string claimsIssuer)
        {
            //保存登陆信息
            List<Claim> claims = new List<Claim>();
            claims.Add(new Claim(ClaimTypes.Sid, token, ClaimValueTypes.String, claimsIssuer));
            claims.Add(new Claim(ClaimTypes.Name, name, ClaimValueTypes.String, claimsIssuer));
            ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, scheme);
            ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
            _httpContextAccessor.HttpContext.SignInAsync(scheme, claimsPrincipal);
        }
    }
}
